﻿using System;
using System.Collections.Generic;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using YArchitech.Controls;
using YArchitech.Revit;
using YArchitech.Revit.RevitExtension;
using YJKArch.Utils;
using YRevitJig;

namespace YJKArch.DimensionModule
{
	public class PracticeDimCreator
	{
		public PracticeDimCreator(DlgPracticeDim dlg, ExternalCommandData cmdData)
		{
			this.m_Dlg = dlg;
			this.m_Revit = cmdData;
			this.m_uiDoc = cmdData.Application.ActiveUIDocument;
			this.m_drawJigCurve = new DrawJigCurve(cmdData);
		}

		public Result Create(ref string message)
		{
			XYZ xyz = null;
			if (this.SelectPoint("选择引出线的起始点", ref xyz) != null)
			{
				return Autodesk.Revit.UI.Result.Cancelled;
			}
			PracticeDimJig practiceDimJig = new PracticeDimJig(this.m_uiDoc, this.m_Dlg);
			XYZ xyz2 = practiceDimJig.PickDimPosition(xyz, "选择引出线的终点");
			if (xyz2 == null)
			{
				practiceDimJig.Dispose();
				return Autodesk.Revit.UI.Result.Cancelled;
			}
			if (xyz.DistanceTo(xyz2) < 0.003)
			{
				YJKMessageBox.Show("两点距离不能太近。");
				practiceDimJig.Dispose();
				return Autodesk.Revit.UI.Result.Succeeded;
			}
			XYZ xyz3 = practiceDimJig.PickDimDirection(xyz, xyz2, "请确定标注方向：");
			if (xyz3 == null)
			{
				practiceDimJig.Dispose();
				return Autodesk.Revit.UI.Result.Cancelled;
			}
			int quadrant = practiceDimJig.GetQuadrant(xyz2, xyz3);
			practiceDimJig.Dispose();
			Autodesk.Revit.DB.View activeView = this.m_uiDoc.ActiveView;
			XYZ xyz4 = activeView.RightDirection;
			if (quadrant == 2 || quadrant == 3)
			{
				xyz4 *= -1.0;
			}
			XYZ xyz5 = activeView.UpDirection;
			if (quadrant == 3 || quadrant == 4)
			{
				xyz5 *= -1.0;
			}
			this.m_Dlg.GetDlgData();
			this.m_DrawingKit = new SpecialCharactorDrawingKit(this.m_Revit, this.m_Dlg.sFontType);
			if (this.m_DrawingKit.TextHeigth < 0.01)
			{
				YJKMessageBox.Show("选择的字体字高太小，不适合本标注。");
				return Autodesk.Revit.UI.Result.Succeeded;
			}
			if (this.m_Dlg.textStrArray.Length < 1)
			{
				YJKMessageBox.Show("标注文字不能为空，请先输入标注文字。");
				return Autodesk.Revit.UI.Result.Succeeded;
			}
			List<string> list = new List<string>();
			if (this.m_Dlg.textStrArray != null)
			{
				foreach (string item in this.m_Dlg.textStrArray)
				{
					list.Add(item);
				}
			}
			XYZ ptThird = xyz2 + AssistFunc.mmToFeet(5.0) * xyz5;
			if (!this.m_Dlg.bTextOnLine && this.m_Dlg.textStrArray.Length == 1)
			{
				ptThird = xyz2 + AssistFunc.mmToFeet(5.0) * xyz4;
			}
			TextNote item2 = this.CreateArrowLine(xyz, xyz2, ptThird, this.m_Dlg.sArrowStyle, this.m_Dlg.sFontType);
			this.m_AllElement.Add(item2);
			if (this.m_Dlg.bTextOnLine)
			{
				this.DrawAnnotation_Underline(xyz2, xyz4, xyz5, list);
			}
			else
			{
				this.DrawAnnotation_Lead(xyz2, xyz4, xyz5, list);
			}
			if (this.m_Dlg.bMutliDotOnLine)
			{
				this.m_Dlg.Enabled = false;
				this.DrawLeaderArrow(this.m_uiDoc, xyz, xyz2, ref item2);
				this.m_Dlg.Enabled = true;
			}
			if (this.m_AllElement.Count > 0)
			{
				ElementSet elementSet = new ElementSet();
				foreach (Element element in this.m_AllElement)
				{
					elementSet.Insert(element);
				}
				RevitVersionFuncs.NewGroup(this.m_uiDoc.Document, elementSet).GroupType.Name = "作法标注";
			}
			return Autodesk.Revit.UI.Result.Succeeded;
		}

		private Result SelectPoint(string statusPrompt, ref XYZ point)
		{
			try
			{
				point = this.m_Revit.Application.ActiveUIDocument.Selection.PickPoint(statusPrompt);
			}
			catch (Exception)
			{
				return Autodesk.Revit.UI.Result.Cancelled;
			}
			return Autodesk.Revit.UI.Result.Succeeded;
		}

		private DetailCurve CreateDetailCurve(XYZ ptStart, XYZ ptEnd)
		{
			Autodesk.Revit.DB.Document document = this.m_Revit.Application.ActiveUIDocument.Document;
			Line line = YJKLineEx.YJKGetBound(ptStart, ptEnd);
			return document.Create.NewDetailCurve(document.ActiveView, line);
		}

		private TextNote CreateArrowLine(XYZ ptStart, XYZ ptEnd, XYZ ptThird, string sArrowStyle, string sFontType)
		{
			Autodesk.Revit.DB.Document document = this.m_Revit.Application.ActiveUIDocument.Document;
			Autodesk.Revit.DB.View activeView = this.m_Revit.Application.ActiveUIDocument.ActiveView;
            TextNote textNode = document.GetTextNode(activeView, ptThird, activeView.RightDirection, activeView.UpDirection, 0.01, (TextAlignFlags)128, (TextNoteLeaderTypes)0, (TextNoteLeaderStyles)1, ptStart, ptEnd, ".");
			string text = "HY_Leader_" + sArrowStyle;
			TextNoteType textNoteType = Helper.GetSelectType<TextNoteType>(document, text) as TextNoteType;
			if (textNoteType == null)
			{
				Element selectType = Helper.GetSelectType<TextNoteType>(document, sFontType);
				Element selectType2 = Helper.GetSelectType<Autodesk.Revit.DB.ElementType>(document, sArrowStyle);
				textNoteType = ((selectType as TextNoteType).Duplicate(text) as TextNoteType);
				textNoteType.get_Parameter(BuiltInParameter.TEXT_SIZE).Set(AssistFunc.mmToFeet(0.5));
				textNoteType.get_Parameter(BuiltInParameter.LEADER_ARROWHEAD).Set(selectType2.Id);
				textNoteType.get_Parameter(BuiltInParameter.TEXT_WIDTH_SCALE).Set(0.2);
			}
			textNode.TextNoteType = textNoteType;
			RevitElementExtension.SetTextNoteCoord(textNode, ptThird);
			textNode.HyGetLeaders().get_Item(0).Elbow = ptEnd;
			textNode.HyGetLeaders().get_Item(0).End = ptStart;
			RevitElementExtension.SetTextNoteWidth(textNode, AssistFunc.mmToFeet(0.5));
			return textNode;
		}

		private Result DrawAnnotation_Underline(XYZ ptBase, XYZ selHorizontalDirection, XYZ selVerticalDirection, List<string> textList)
		{
			Autodesk.Revit.DB.View activeView = this.m_Revit.Application.ActiveUIDocument.ActiveView;
			Plane planeWithSketchPlane = RevitVersionFuncs.GetPlaneWithSketchPlane(activeView.SketchPlane);
			XYZ xvec = planeWithSketchPlane.XVec;
			XYZ yvec = planeWithSketchPlane.YVec;
			double num = (double)this.m_Revit.Application.ActiveUIDocument.ActiveView.Scale;
			double num2 = this.m_DrawingKit.TextHeigth * this.m_DrawingKit.TextWidthScale * num * RevitDocumentExtension.GetTextWidthFactory();
			double num3 = this.m_DrawingKit.TextHeigth * 2.0 * num;
			Transform identity = Transform.Identity;
			identity.Origin = activeView.Origin;
			identity.BasisX = planeWithSketchPlane.XVec;
			identity.BasisY = planeWithSketchPlane.YVec;
			identity.BasisZ = identity.BasisX.CrossProduct(identity.BasisY);
			Transform inverse = identity.Inverse;
			int num4 = 0;
			foreach (string str in textList)
			{
				int num5 = SpecialCharactorDrawingKit.GetLength(str) + 1;
				if (num4 < num5)
				{
					num4 = num5;
				}
			}
			double num6 = (double)num4 * num2 * this.m_DrawingKit.CharWidthCoefficient;
			XYZ xyz = this.TransformPoint(ptBase, inverse);
			for (int i = 0; i < textList.Count; i++)
			{
				string text = textList[i];
				double num7 = xyz.X;
				double num8 = xyz.X;
				double num9 = xyz.Y;
				double num10 = xyz.Y;
				if (selVerticalDirection.IsAlmostEqualTo(yvec))
				{
					num9 += (double)(textList.Count - i - 1) * num3;
				}
				else
				{
					num9 += (double)(-(double)(i + 1)) * num3;
				}
				num10 = num9 + num3;
				SpecialCharactorDrawingKit.GetLength(text);
				if (selHorizontalDirection.IsAlmostEqualTo(xvec))
				{
					num8 += num6;
				}
				else
				{
					num7 -= num6;
				}
				XYZ xyz2 = new XYZ(num7, num9, xyz.Z);
				xyz2 = this.TransformPoint(xyz2, identity);
				XYZ xyz3 = new XYZ(num8, num10, xyz.Z);
				xyz3 = this.TransformPoint(xyz3, identity);
				this.m_AllElement.AddRange(this.DrawSingleRowAnnotationLeftBottomLine(xyz2, xyz3, selHorizontalDirection));
				this.m_AllElement.AddRange(this.DrawSingleRowAnnotation(text, xyz2, xyz3, num2, selHorizontalDirection));
			}
			return Autodesk.Revit.UI.Result.Succeeded;
		}

		private Result DrawAnnotation_Lead(XYZ ptBase, XYZ selHorizontalDirection, XYZ selVerticalDirection, List<string> textList)
		{
			double num = (double)this.m_Revit.Application.ActiveUIDocument.ActiveView.Scale;
			double num2 = this.m_DrawingKit.TextHeigth * this.m_DrawingKit.TextWidthScale * num / 2.0;
			double num3 = this.m_DrawingKit.TextHeigth * num * this.m_DrawingKit.CharHeightCoefficient;
			Autodesk.Revit.DB.View activeView = this.m_Revit.Application.ActiveUIDocument.ActiveView;
			Plane planeWithSketchPlane = RevitVersionFuncs.GetPlaneWithSketchPlane(activeView.SketchPlane);
			Transform identity = Transform.Identity;
			identity.Origin = activeView.Origin;
			identity.BasisX = planeWithSketchPlane.XVec;
			identity.BasisY = planeWithSketchPlane.YVec;
			identity.BasisZ = identity.BasisX.CrossProduct(identity.BasisY);
			Transform inverse = identity.Inverse;
			XYZ xyz = this.TransformPoint(ptBase, inverse);
			XYZ xyz2;
			if (selVerticalDirection.IsAlmostEqualTo(planeWithSketchPlane.YVec))
			{
				xyz2 = xyz + new XYZ(0.0, (double)(textList.Count - 1) * num3, 0.0);
			}
			else
			{
				xyz2 = xyz - new XYZ(0.0, (double)(textList.Count - 1) * num3, 0.0);
			}
			xyz2 = this.TransformPoint(xyz2, identity);
			if (!ptBase.IsAlmostEqualTo(xyz2))
			{
				this.m_AllElement.Add(this.CreateDetailCurve(ptBase, xyz2));
			}
			for (int i = 0; i < textList.Count; i++)
			{
				string text = textList[i];
				double num4 = xyz.Y;
				if (selVerticalDirection.IsAlmostEqualTo(planeWithSketchPlane.YVec))
				{
					num4 += (double)(textList.Count - i - 1) * num3;
				}
				else
				{
					num4 -= (double)i * num3;
				}
				double num5 = AssistFunc.mmToFeet(500.0);
				double num6 = num4 - num3 / 2.0;
				double num7 = num4 + num3 / 2.0;
				double num8;
				double num9;
				double num10;
				if (selHorizontalDirection.IsAlmostEqualTo(planeWithSketchPlane.XVec))
				{
					num8 = xyz.X + num5;
					num9 = num8;
					num10 = num9 + (double)SpecialCharactorDrawingKit.GetLength(text) * num2 * this.m_DrawingKit.CharWidthCoefficient * this.m_DrawingKit.TextWidthScale;
				}
				else
				{
					num8 = xyz.X - num5;
					num10 = num8;
					num9 = num10 - (double)SpecialCharactorDrawingKit.GetLength(text) * num2 * this.m_DrawingKit.CharWidthCoefficient * this.m_DrawingKit.TextWidthScale;
				}
				XYZ xyz3 = new XYZ(xyz.X, num4, xyz.Z);
				xyz3 = this.TransformPoint(xyz3, identity);
				XYZ xyz4 = new XYZ(num8, num4, xyz.Z);
				xyz4 = this.TransformPoint(xyz4, identity);
				this.m_AllElement.Add(this.CreateDetailCurve(xyz3, xyz4));
				XYZ xyz5 = new XYZ(num9, num6, xyz.Z);
				xyz5 = this.TransformPoint(xyz5, identity);
				XYZ xyz6 = new XYZ(num10, num7, xyz.Z);
				xyz6 = this.TransformPoint(xyz6, identity);
				this.m_AllElement.AddRange(this.DrawSingleRowAnnotation(text, xyz5, xyz6, num2, selHorizontalDirection));
			}
			return Autodesk.Revit.UI.Result.Succeeded;
		}

		private List<Element> DrawSingleRowAnnotationLeftBottomLine(XYZ rectangleMin, XYZ rectangleMax, XYZ selHorizontalDirection)
		{
			List<Element> list = new List<Element>();
			Autodesk.Revit.DB.View activeView = this.m_Revit.Application.ActiveUIDocument.ActiveView;
			Plane planeWithSketchPlane = RevitVersionFuncs.GetPlaneWithSketchPlane(activeView.SketchPlane);
			Transform identity = Transform.Identity;
			identity.Origin = activeView.Origin;
			identity.BasisX = planeWithSketchPlane.XVec;
			identity.BasisY = planeWithSketchPlane.YVec;
			identity.BasisZ = identity.BasisX.CrossProduct(identity.BasisY);
			Transform inverse = identity.Inverse;
			XYZ xyz = this.TransformPoint(rectangleMin, inverse);
			XYZ xyz2 = this.TransformPoint(rectangleMax, inverse);
			XYZ xyz3 = new XYZ(xyz2.X, xyz.Y, xyz.Z);
			xyz3 = this.TransformPoint(xyz3, identity);
			list.Add(this.CreateDetailCurve(rectangleMin, xyz3));
			Autodesk.Revit.DB.Document document = this.m_Revit.Application.ActiveUIDocument.Document;
			if (selHorizontalDirection.IsAlmostEqualTo(planeWithSketchPlane.XVec))
			{
				XYZ xyz4 = new XYZ(xyz.X, xyz2.Y, xyz.Z);
				xyz4 = this.TransformPoint(xyz4, identity);
				list.Add(this.CreateDetailCurve(rectangleMin, xyz4));
			}
			else
			{
				list.Add(this.CreateDetailCurve(xyz3, rectangleMax));
			}
			return list;
		}

		private List<Element> DrawSingleRowAnnotation(string text, XYZ rectangleMin, XYZ rectangleMax, double offsetX, XYZ selHorizontalDirection)
		{
			List<Element> list = new List<Element>();
			Autodesk.Revit.DB.View activeView = this.m_Revit.Application.ActiveUIDocument.ActiveView;
			Plane planeWithSketchPlane = RevitVersionFuncs.GetPlaneWithSketchPlane(activeView.SketchPlane);
			Transform identity = Transform.Identity;
			identity.Origin = activeView.Origin;
			identity.BasisX = planeWithSketchPlane.XVec;
			identity.BasisY = planeWithSketchPlane.YVec;
			identity.BasisZ = identity.BasisX.CrossProduct(identity.BasisY);
			Transform inverse = identity.Inverse;
			XYZ xyz = this.TransformPoint(rectangleMin, inverse);
			XYZ xyz2 = this.TransformPoint(rectangleMax, inverse);
			Autodesk.Revit.DB.Document document = this.m_Revit.Application.ActiveUIDocument.Document;
			if (selHorizontalDirection.IsAlmostEqualTo(planeWithSketchPlane.XVec))
			{
				SpecialCharactorDrawingKit.TextHorizontalAlignment hAlignment = SpecialCharactorDrawingKit.TextHorizontalAlignment.THA_LEFT;
				XYZ xyz3 = xyz + new XYZ(0.0, xyz2.Y - xyz.Y, 0.0) / 2.0;
				xyz3 += new XYZ(offsetX, 0.0, 0.0);
				xyz3 = this.TransformPoint(xyz3, identity);
				list.AddRange(this.m_DrawingKit.DrawSingleRowCharactors(xyz3, text, hAlignment, SpecialCharactorDrawingKit.TextVerticalAlignment.TVA_MIDDLE));
			}
			else
			{
				SpecialCharactorDrawingKit.TextHorizontalAlignment hAlignment = SpecialCharactorDrawingKit.TextHorizontalAlignment.THA_RIGHT;
				XYZ xyz4 = xyz2 - new XYZ(0.0, xyz2.Y - xyz.Y, 0.0) / 2.0;
				xyz4 -= new XYZ(offsetX, 0.0, 0.0);
				xyz4 = this.TransformPoint(xyz4, identity);
				list.AddRange(this.m_DrawingKit.DrawSingleRowCharactors(xyz4, text, hAlignment, SpecialCharactorDrawingKit.TextVerticalAlignment.TVA_MIDDLE));
			}
			return list;
		}

		private void DrawLeaderArrow(UIDocument UIDoc, XYZ ptStart, XYZ ptEnd, ref TextNote arrowNote)
		{
			int num = 1;
			for (;;)
			{
				try
				{
					XYZ point = UIDoc.Selection.PickPoint("请选择标记点");
					XYZ end = Geometry.CalculateFootPoint(ptStart, ptEnd, point);
					arrowNote.AddLeader(0);
					arrowNote.HyGetLeaders().get_Item(num).Elbow = ptEnd;
					arrowNote.HyGetLeaders().get_Item(num).End = end;
					UIDoc.Document.Regenerate();
					num++;
					continue;
				}
				catch
				{
				}
				break;
			}
		}

		private XYZ TransformPoint(XYZ point, Transform transform)
		{
			double x = point.X;
			double y = point.Y;
			double z = point.Z;
			XYZ xyz = transform.get_Basis(0);
			XYZ xyz2 = transform.get_Basis(1);
			XYZ xyz3 = transform.get_Basis(2);
			XYZ origin = transform.Origin;
			double num = x * xyz.X + y * xyz2.X + z * xyz3.X + origin.X;
			double num2 = x * xyz.Y + y * xyz2.Y + z * xyz3.Y + origin.Y;
			double num3 = x * xyz.Z + y * xyz2.Z + z * xyz3.Z + origin.Z;
			return new XYZ(num, num2, num3);
		}

		private ExternalCommandData m_Revit;

		private DlgPracticeDim m_Dlg;

		private List<Element> m_AllElement = new List<Element>();

		private SpecialCharactorDrawingKit m_DrawingKit;

		private UIDocument m_uiDoc;

		private DrawJigCurve m_drawJigCurve;
	}
}
